package org.leumasjaffe.initiativeTracker.view;


import java.awt.Color;
import java.awt.Font;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

import org.leumasjaffe.initiativeTracker.entity.IStatus;
import org.leumasjaffe.util.io.PortableScanner;

@SuppressWarnings("serial")
public class CharacterPanel extends JPanel implements IStatus{
	private static final Font basicFont = new Font(null, Font.PLAIN, 12);
	private static final Font statFont = new Font(null, Font.PLAIN, 10);
	private Font altFont = null;
	
	private int dis;
		
	private static final int defenseBlock;
	private static final int markPos;
	private static final int blindPos;
	private static final int slowPos;
	private static final int pronePos;
	private static final int weakPos;
	private static final int deafPos;
	private static final int restrainPos;
	private static final int ongoingPos;
	
	private static final int markSize;
	private static final int blindSize;
	private static final int slowSize;
	private static final int proneSize;
	private static final int weakSize;
	private static final int deafSize;
	private static final int restrainSize;
	private static final int ongoingSize;
	
	static {
		if (System.getProperty("os.name").contains("Windows")) {
			defenseBlock = 40;
			markPos = 330;
			blindPos = 405;
			slowPos = 485;
			pronePos = 557;
			weakPos = 624;
			deafPos = 714;
			restrainPos = 814;
			ongoingPos = 915;
			
			markSize = 80;
			blindSize = 80;
			slowSize = 80;
			proneSize = 70;
			weakSize = 90;
			deafSize = 103;
			restrainSize = 105;
			ongoingSize = 80;
		}
		else {
			defenseBlock = 30;
			markPos = 300;
			blindPos = 370;
			slowPos = 445;
			pronePos = 520;
			weakPos = 585;
			deafPos = 675;
			restrainPos = 775;
			ongoingPos = 875;
			
			markSize = 80;
			blindSize = 80;
			slowSize = 80;
			proneSize = 70;
			weakSize = 95;
			deafSize = 110;
			restrainSize = 120;
			ongoingSize = 80;
		}
	}

	private JCheckBox marked = new JCheckBox("Marked");
	private JCheckBox cursed = new JCheckBox("Cursed");

	private JLabel nameB = new JLabel();
	private JLabel acB = new JLabel();
	private JLabel fortB = new JLabel();
	private JLabel refB = new JLabel();
	private JLabel willB = new JLabel();
	private JLabel hpB = new JLabel();
	
	private JCheckBox blinded = new JCheckBox("Blinded");
	private JCheckBox dazed = new JCheckBox("Dazed");
	private JCheckBox deafened = new JCheckBox("Deafened");
	private JCheckBox dominated = new JCheckBox("Dominated");
	private JCheckBox immobilized = new JCheckBox("Immobilized");
	private JCheckBox petrified = new JCheckBox("Petrified");
	private JCheckBox prone = new JCheckBox("Prone");
	private JCheckBox restrained = new JCheckBox("Restrained");
	private JCheckBox slowed = new JCheckBox("Slowed");
	private JCheckBox stunned = new JCheckBox("Stunned");
	private JCheckBox unconscious = new JCheckBox("Unconscious");
	private JCheckBox weakened = new JCheckBox("Weakened");
	private JCheckBox dotBox = new JCheckBox("Ongoing");
	private JCheckBox reDot = new JCheckBox();

	private JCheckBox target = new JCheckBox();

	public final JCheckBox[] arrayCheckbox = {this.blinded, this.dazed, this.deafened, this.dominated,
			this.immobilized, this.petrified, this.prone, this.restrained, this.slowed, this.stunned, 
			this.unconscious, this.weakened, this.marked, this.cursed, this.dotBox};
	
	public CharacterPanel(int dis, Color outline) {
		this.dis = dis;
		
		this.nameB.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createLineBorder(outline), BorderFactory.createRaisedBevelBorder()));
		this.nameB.setHorizontalAlignment(SwingConstants.CENTER);
		this.nameB.setVerticalAlignment(SwingConstants.CENTER);
		this.acB.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		this.acB.setHorizontalAlignment(SwingConstants.CENTER);
		this.fortB.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		this.fortB.setHorizontalAlignment(SwingConstants.CENTER);
		this.refB.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		this.refB.setHorizontalAlignment(SwingConstants.CENTER);
		this.willB.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		this.willB.setHorizontalAlignment(SwingConstants.CENTER);
		this.hpB.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		this.hpB.setHorizontalAlignment(SwingConstants.CENTER);
		
		setFonts();
		setLayout(null);
		setBounds();
		build();
		setVisible(true);
	}
	
	public void update() {
		this.target.setSelected(false);
	}
	
	public void build() {
		add(this.target);
		add(this.reDot);
		add(this.nameB);
		add(this.acB);
		add(this.fortB);
		add(this.refB);
		add(this.willB);
		add(this.hpB);
		for (JCheckBox j : this.arrayCheckbox)
			add(j);
	}
	
	/**
	 * Sets the positions (bounds) of all of the labels and buttons
	 */
	private void setBounds() {
		if (this.dis == 0)
			this.nameB.setBounds(50, 11, 140, 20);
		else
			this.nameB.setBounds(50, 1, 140, 40);
				
		this.marked.setBounds(markPos, 1, markSize, 20);
		this.cursed.setBounds(markPos, 21, markSize, 20);

		this.blinded.setBounds(blindPos, 1, blindSize, 20);
		this.petrified.setBounds(blindPos, 21, blindSize, 20);

		this.slowed.setBounds(slowPos, 1, slowSize, 20);
		this.stunned.setBounds(slowPos, 21, slowSize, 20);

		this.dazed.setBounds(pronePos, 1, proneSize, 20);
		this.prone.setBounds(pronePos, 21, proneSize, 20);

		this.dominated.setBounds(weakPos, 1, weakSize, 20);
		this.weakened.setBounds(weakPos, 21, weakSize, 20);

		this.immobilized.setBounds(deafPos, 1, deafSize, 20);
		this.deafened.setBounds(deafPos, 21, deafSize, 20);

		this.restrained.setBounds(restrainPos, 1, restrainSize, 20);
		this.unconscious.setBounds(restrainPos, 21, restrainSize, 20);

		this.target.setBounds(20, 11, 25, 20);

		this.dotBox.setBounds(ongoingPos, 11, ongoingSize, 20);
		this.reDot.setBounds(ongoingPos + ongoingSize, 11, 25, 20);

		this.acB.setBounds(205 + 2*defenseBlock, 0, defenseBlock, 20);
		this.hpB.setBounds(195, 0, 2*defenseBlock+5, 20);
		this.fortB.setBounds(195, 22, defenseBlock, 20);
		this.refB.setBounds(200 + defenseBlock, 22, defenseBlock, 20);
		this.willB.setBounds(205 + 2*defenseBlock, 22, defenseBlock, 20);

	}
	
	private void setFonts() {
		for (JCheckBox cBox : this.arrayCheckbox)
			cBox.setFont(basicFont);
		this.hpB.setFont(statFont);
		this.acB.setFont(statFont);
		this.fortB.setFont(statFont);
		this.refB.setFont(statFont);
		this.willB.setFont(statFont);
	}
	
	public boolean checkFont() {
		return this.altFont == null;
	}
	
	@Override
	public void setFont(Font f) {
		this.altFont = f;
	}
	
	public int sizeName(String name) {	
		if (name.length() > 18 && this.altFont == null){
			double n = 19.0 * 13.0 / (double)name.length();
			
			if (n<10) {
				if (this.dis == 0) { 
					int input = PortableScanner.nextInt(
							"\nChoose index to split (first space is at "
							+ name.indexOf(' ') + ")");
					this.dis = input;
				}
				
				String a = name.substring(0, this.dis);
				String b = name.substring(this.dis);
				this.nameB.setText("<html>" + a + "<br>" + b + "</html>");
				n = n + 3;
			}
			
			this.altFont = new Font(null, Font.PLAIN, (int)n);
			this.nameB.setFont(this.altFont);
		}
		return this.dis;
	}
	
	public void setNameText(String text) {
		if (this.altFont != null)
			this.nameB.setFont(this.altFont);
		this.nameB.setText(text);
	}
	
	public void setHPText(String text) {
		this.hpB.setText(text);
	}
	
	public void setArmorText(String text) {
		this.acB.setText(text);
	}
	
	public void setFortText(String text) {
		this.fortB.setText(text);
	}
	
	public void setRefText(String text) {
		this.refB.setText(text);
	}
	
	public void setWillText(String text) {
		this.willB.setText(text);
	}
	
	public int getDis() {
		return this.dis;
	}

	public void setDis(int dis) {
		this.dis = dis;
	}

	public boolean isBleeding() {
		return this.dotBox.isSelected();
	}

	public boolean renewOngoing() {
		boolean bool = this.reDot.isSelected();
		this.reDot.setSelected(false);
		return bool;
	}

	public JCheckBox getUnconscious() {
		return this.unconscious;
	}

	public boolean isTarget() {
		return this.target.isSelected();
	}

	public Font getAltFont() {
		return this.altFont;
	}

	public int getLength() {
		return ongoingPos + 120;
	}

	public String getNameText() {
		return this.nameB.getText();
	}

	public int getNumStat() {
		return this.arrayCheckbox.length;
	}

	public boolean getStatus(int i) {
		return this.arrayCheckbox[i].isSelected();
	}

	@Override
	public int statusAsBitString() {
		int temp = 0;
		for (int i = 0; i < this.arrayCheckbox.length; i++)
			if (this.arrayCheckbox[i].isSelected()) temp += 1 << i;
		return temp;
	}
	
	@Override
	public void readStatus(int bits) {
		for (int i = 0; i < this.arrayCheckbox.length; i++)
			if ((1 & bits >> i) == 1) this.arrayCheckbox[i].setSelected(true);
			else this.arrayCheckbox[i].setSelected(false);
	}

}
